package cn.windy.samary.module.admin.interceptor;

import cn.windy.samary.module.admin.common.UserLine;
import cn.windy.samary.module.admin.entity.OperateLog;
import cn.windy.samary.module.admin.service.IOperateLogService;
import cn.windy.samary.utils.InterceptUtil;
import cn.windy.samary.utils.MacUtil;
import cn.windy.samary.utils.RequestUtil;
import cn.windy.samary.utils.ShiroUtils;
import org.apache.commons.lang.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Date;

/**
 * 操作日志记录
 *
 * @author zyl
 * @date 2018/5/11 10:40
 */
@Aspect
@Component
public class OperateLogInterceptor {

    @Resource
    private IOperateLogService operateLogService;
    @Resource
    private ThreadPoolTaskExecutor executor;

    @Around("@annotation(cn.windy.samary.core.annotation.OpLog)")
    public Object writeLod(ProceedingJoinPoint joinPoint) throws Throwable {
        long time1 = System.currentTimeMillis();
        Object proceed = joinPoint.proceed();
        long time2 = System.currentTimeMillis();
        HttpServletRequest request = InterceptUtil.getRequest(joinPoint);
        if (request == null) {
            request = RequestUtil.getRequest();
        }
        UserLine user = ShiroUtils.getUserLine();
        saveLog(joinPoint, request, user, time1, time2);

        return proceed;
    }

    /**
     * 添加操作日志
     */
    private void saveLog(ProceedingJoinPoint joinPoint, HttpServletRequest request, UserLine user, long time1, long time2) {
        executor.execute(new Runnable() {
            @Override
            public void run() {
                OperateLog log = new OperateLog();
                Object target = joinPoint.getTarget();
                Class<?> clazz = target.getClass();
                MethodSignature signature = (MethodSignature) joinPoint.getSignature();
                Method method = signature.getMethod();
                log.setOperateController(clazz.getName());
                log.setOperateMethod(method.getName());
                if (user != null) {
                    log.setOperateUserId(user.getId());
                    log.setOperateUser(user.getUsername());
                }
                String operaterDesc = InterceptUtil.getOperaterDesc(joinPoint);
                if (StringUtils.isBlank(operaterDesc)) {
                    return;
                }
                log.setOperateInfo(operaterDesc);
                String ipAddr = MacUtil.getIpAddr(request);
                log.setOperateIp(ipAddr);
                String os = RequestUtil.getOs(request);
                log.setOperateDcvice(os);
                String browser = RequestUtil.getBrowser(request);
                log.setOperateBrowser(browser);
                Date date1 = new Date(time1);
                Date date2 = new Date(time2);
                long tt = time2 - time1;
                log.setStartTime(date1);
                log.setEndTime(date2);
                log.setSpendTime(tt);
                log.setOperateTime(date1);
                if (!browser.contains("UNKNOWN")) {
                    operateLogService.insertSelective(log);
                }
            }
        });
    }

}
